package com.iot08.admin.utils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;

/**
 * @author cwj
 * @description
 * @date 2025/1/2 14:35
 **/
public class WeChatPayUtils {


    // SHA256 哈希方法
    public static String sha256(String data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            throw new RuntimeException("SHA-256 哈希计算失败", e);
        }
    }

    // 使用 RSA 签名
    public static String rsaSign(String data, PrivateKey privateKey) throws Exception {
        // 获取私钥
        //PrivateKey key = getPrivateKey(privateKey);

        // 创建签名对象
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);

        // 更新数据
        signature.update(data.getBytes(StandardCharsets.UTF_8));

        // 签名
        byte[] signedData = signature.sign();

        // 使用 Base64 编码签名
        return Base64.getEncoder().encodeToString(signedData);
    }

    // 将字节数组转为十六进制字符串
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    // 获取私钥对象
   /* public static PrivateKey getPrivateKey(String privateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(new java.security.spec.PKCS8EncodedKeySpec(keyBytes));
    }*/


    /**
     * @description 生成随机字符串
     * @author cwj
     * @param []
     * @return java.lang.String
     * @date @time 2025/1/2 15:18
     **/
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }


    /**
     * @description 构建请求签名字符串
     * @author cwj
     * @param [httpMethod, url, timestamp, nonceStr, requestBody]
     * @return java.lang.String
     * @date @time 2025/1/2 15:13
     **/
    public static String buildSignString(String httpMethod, String url, String timestamp, String nonceStr, String requestBody) {
        return httpMethod + "\n" +
                url + "\n" +
                timestamp + "\n" +
                nonceStr + "\n" +
                requestBody + "\n"; // 末尾添加换行符
    }

    /**
     * @description 构建支付的签名字符串
     * @author cwj
     * @param [appid, timeStamp, nonceStr, prepayId]
     * @return java.lang.String
     * @date @time 2025/1/3 9:23
     **/
    public static String buildPaySignString(String appid,String timestamp,String nonceStr,String prepayId){
        return appid + "\n" +
                timestamp + "\n" +
                nonceStr + "\n" +
                prepayId +"\n"; // 末尾添加换行符
    }


    /**
     * @description 生成签名
     * @author cwj
     * @param [signString, privateKey]
     * @return java.lang.String
     * @date @time 2025/1/2 15:14
     **/
    public static String generateSignature(String signString, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(signString.getBytes(StandardCharsets.UTF_8));
        byte[] signedData = signature.sign();
        return Base64.getEncoder().encodeToString(signedData);
    }


    /**
     * @description 构建下单的签名字符串
     * @author cwj
     * @param [signature, timestamp, nonceStr]
     * @return java.lang.String
     * @date @time 2025/1/2 15:15
     **/
    public static String buildAuthorizationHeader( String mchid, String nonceStr,String signature,String timeStamp,String serialNo) {
        return "WECHATPAY2-SHA256-RSA2048 mchid=\""+mchid+"\"," +
                "nonce_str=\"" + nonceStr + "\"," +
                "signature=\"" + signature + "\"," +
                "timestamp=\""+timeStamp+"\","+
                "serial_no=\""+serialNo+"\"";
    }



    /**
     * @description 验签
     * @author cwj
     * @param [publicKey, signature, signString]
     * @return boolean
     * @date @time 2025/1/4 9:16
     **/
    public static boolean verifySignature(PublicKey publicKey, String signature, String signString) throws Exception {
        Signature verify = Signature.getInstance("SHA256withRSA");
        verify.initVerify(publicKey);
        verify.update(signString.getBytes(StandardCharsets.UTF_8));
        byte[] decodedSignature = Base64.getDecoder().decode(signature);
        return verify.verify(decodedSignature);
    }


    /**
     * @description 构建支付通知签名字符串
     * @author cwj
     * @param [timestamp, nonceStr, requestBody]
     * @return java.lang.String
     * @date @time 2025/1/4 9:33
     **/
    public static String buildPayNotifySignString(String timestamp,String nonceStr,String requestBody){
        return timestamp + "\n" +
                nonceStr + "\n" +
                requestBody +"\n"; // 末尾添加换行符
    }


}
